package com.coco.thread.wait;

/**
 * wait 挂起
 * wait()方法的作用是将当前运行的线程挂起（即让其进入阻塞状态），
 * 直到notify或notifyAll方法来唤醒线程.
 *
 * wait(long timeout)，该方法与wait()方法类似，唯一的区别就是在指定时间内，
 * 如果没有notify或notifAll方法的唤醒，也会自动唤醒。
 */
public class MyWait {

    public static volatile boolean go = false;

    public static void main(String[] args) throws InterruptedException {

        final MyWait myWait = new MyWait();

        Runnable waitTask = new Runnable() {
            @Override
            public void run() {
                try {
                    myWait.shouldGo();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"   finished Execution");
            }
        };
        Runnable notifyTask = new Runnable() {
            @Override
            public void run() {
                myWait.go();
                System.out.println(Thread.currentThread().getName()+"   finished Execution");
            }
        };

        Thread t1 = new Thread(waitTask,"WT1");
        Thread t2 = new Thread(waitTask,"WT2");
        Thread t3 = new Thread(waitTask,"WT3");
        Thread t4 = new Thread(notifyTask,"NT1");
        t1.start();
        t2.start();
        t3.start();

        Thread.sleep(2000);
        t4.start();


    }

    public synchronized void  shouldGo() throws InterruptedException {
            while (go!=true){
                System.out.println(Thread.currentThread().getName()+"   is go to wait on this object");
                wait();
                System.out.println(Thread.currentThread().getName()+"   is woken up");
            }
    }


    public synchronized void go(){
        while (go==false){
            System.out.println(Thread.currentThread().getName()+"   is go to notify all or thread waiting on this object");
            go = true;
            notify();
        }
    }


}
